// ==UserScript== // @name 文本链接自动识别为超链接 // @version 0.1.3 // @description 通过正则表达式识别文本中的链接,并转换为超链接 // @author DreamNya // @match *://*/* // @grant none // @run-at document-start // @license MIT // @namespace https://greasyfork.org/users/809466 // ==/UserScript== //文本链接识别正则 const reg = /https?:\/\/[\w\.-]+\.\w+(:\d{1,5})?(\/[#%\w?&.=\-@]+)*/g; //忽略标签类型 const ignore = ['SCRIPT', 'STYLE', 'A', 'TEXTAREA', 'NOSCRIPT']; //脚本运行时遍历所有节点 queryElement(document) //后续通过观察器监视 let obs = new MutationObserver(m => { m.forEach(mm => { formatHref(mm.target, mm.addedNodes) mm.addedNodes.forEach(i => queryElement(i)) }) }); obs.observe(document, { subtree: true, childList: true }); function queryElement(element) { //用了点语法糖 [...(element.querySelectorAll?.("*") ?? [])].forEach(i => formatHref(i, i.childNodes)) } function formatHref(target, childNodes) { //忽略标签 if (ignore.find(n => n == target.nodeName)) return let mark = false; //文本链接构造为a标签 [...childNodes].forEach(c => { if (c.nodeName == '#text' && c.textContent.match(reg)) { c.textContent = c.textContent.replace(reg, (m) => { return `${m}` }) mark = true } }) //格式化标签 if (mark) { //console.log(target,target.nodeName) target.innerHTML = target.innerHTML.replace(/<a /g, "").replace(/' target='_blank'>/g, "' target='_blank'>") } }